1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include <cstdio> #include <algorithm> #include <cmath> const int maxn = 5e5 + 5; using namespace std; struct E{ int to, nxt; }e[maxn << 1]; int head[maxn], tot = 0; void addedge(int u, int v){ e[++tot].to = v, e[tot].nxt = head[u]; head[u] = tot; } int Min[maxn << 1][25], tdx = 0; int link[maxn], dep[maxn], x[maxn << 1][25]; void dfs(int cur, int fa){ dep[cur] = dep[fa] + 1; Min[++tdx][0] = dep[cur]; x[tdx][0] = cur; for (int i = head[cur]; i; i = e[i].nxt){ int v = e[i].to; if (v != fa){ dfs(v, cur); Min[++tdx][0] = dep[cur]; x[tdx][0] = cur; } } link[cur] = tdx; } void ins(){ for (int j = 1; j <= 24; j++) for (int i = 1; i + (1 << j) - 1 <= tdx; i++) if (Min[i][j - 1] < Min[i + (1 << (j - 1))][j - 1]) x[i][j] = x[i][j - 1], Min[i][j] = Min[i][j - 1]; else x[i][j] = x[i + (1 << (j - 1))][j - 1], Min[i][j] = Min[i + (1 << (j - 1))][j - 1]; } int Query(int l, int r){ int k = (int)log2(r - l + 1); if (Min[l][k] < Min[r - (1 << k) + 1][k]) return x[l][k]; else return x[r - (1 << k) + 1][k]; } int n, Q, rt; int main(){ scanf("%d%d%d", &n, &Q, &rt); for (int u, v, i = 1; i < n; i++){ scanf("%d%d", &u, &v); addedge(u, v); addedge(v, u); } dfs(rt, 0); ins();
while (Q--){ int u, v; scanf("%d%d", &u, &v); if (link[u] > link[v]) swap(u, v); printf("%d\n", Query(link[u], link[v])); } return 0; }
|